package com.example.opengl.render.magiccube

import com.example.opengl.R

/**
 * @author: Mr.You
 * @create: 2023-08-08 15:49
 * @description:
 **/



object MagicCubeModel {
    private val PLANE_NUM = 3 * 6 // 面数
    private val SQUARE_NUM_PER_PLANE = 9 // 每面方块数
    private val VERTEXT_NUM_PER_SQUARE = 4 // 每个方块顶点数
    private val DIMENSION_PER_VERTEXT = 3 // 每个顶点坐标维度
    private val DIMENSION_PER_TEXTURE = 2 // 每个纹理坐标维度
    private val SQUARE_SIDE = 0.7f // 每个方块的边长
    private val HALF_PLANE_SIDE = 1.5f * SQUARE_SIDE //每个面的边长的一半
    private val RESOURCE_ID = intArrayOf( // 图片资源id
        R.mipmap.image1, R.mipmap.image2, R.mipmap.image3, R.mipmap.image4,
        R.mipmap.image5, R.mipmap.image6, R.drawable.image
    )

    // 顶点坐标数组
    private val vertex = Array(PLANE_NUM) {
        Array(SQUARE_NUM_PER_PLANE) {
            Array(VERTEXT_NUM_PER_SQUARE) {
                FloatArray(DIMENSION_PER_VERTEXT)
            }
        }
    }

    // 纹理坐标数组
    private val texture = Array(PLANE_NUM) {
        Array(SQUARE_NUM_PER_PLANE) {
            Array(VERTEXT_NUM_PER_SQUARE) {
                FloatArray(DIMENSION_PER_TEXTURE)
            }
        }
    }

    // 贴图资源数组
    private val mipmap = Array(PLANE_NUM) { IntArray(SQUARE_NUM_PER_PLANE) }

    init {
        initModel()
    }

    // 初始化模型顶点坐标和纹理坐标
    private fun initModel() {
        for (i in 0..2) { // 遍历三视图
            initView(i)
        }
    }

    // 初始化三视图顶点坐标和纹理坐标
    private fun initView(direction: Int) {
        val baseIndex = direction * 6
        val axis = 2 - direction // 固定的坐标轴
        for (i in 0..5) {
            val planeIndex = baseIndex + i
            val value = HALF_PLANE_SIDE - (i + 1) / 2 * SQUARE_SIDE
            initPlane(planeIndex, axis, value)
            initMipmap(direction, planeIndex, i)
        }
    }

    // 初始化贴图资源
    private fun initMipmap(direction: Int, planeIndex: Int, seq: Int) {
        val near = direction * 2
        val far = near + 1
        val inside = 6
        val index = if (seq == 0) near else if (seq == 5) far else inside
        for (i in 0 until SQUARE_NUM_PER_PLANE) {
            mipmap[planeIndex][i] = RESOURCE_ID[index]
        }
    }

    // 初始化一个面顶点坐标和纹理坐标
    private fun initPlane(planeIndex: Int, axis: Int, value: Float) {
        for (i in 0..8) {
            initSquare(planeIndex, i, axis, value)
        }
    }

    // 初始化一个方块顶点坐标和纹理坐标
    private fun initSquare(planeIndex: Int, squareIndex: Int, axis: Int, value: Float) {
        val row = HALF_PLANE_SIDE - SQUARE_SIDE * (squareIndex / 3)
        val col = -HALF_PLANE_SIDE + SQUARE_SIDE * (squareIndex % 3)
        when (axis) {
            0 -> {
                var i = 0
                while (i < 4) {
                    vertex[planeIndex][squareIndex][i][0] = value
                    vertex[planeIndex][squareIndex][i][1] = row - SQUARE_SIDE * (i / 2)
                    vertex[planeIndex][squareIndex][i][2] = col + SQUARE_SIDE * (i % 2)
                    i++
                }
            }

            1 -> {
                var i = 0
                while (i < 4) {
                    vertex[planeIndex][squareIndex][i][0] = col + SQUARE_SIDE * (i % 2)
                    vertex[planeIndex][squareIndex][i][1] = value //axis
                    vertex[planeIndex][squareIndex][i][2] = row - SQUARE_SIDE * (i / 2)
                    i++
                }
            }

            2 -> {
                var i = 0
                while (i < 4) {
                    vertex[planeIndex][squareIndex][i][0] = col + SQUARE_SIDE * (i % 2)
                    vertex[planeIndex][squareIndex][i][1] = row - SQUARE_SIDE * (i / 2)
                    vertex[planeIndex][squareIndex][i][2] = value
                    i++
                }
            }
        }
        for (i in 0..3) {
            texture[planeIndex][squareIndex][i][0] = (i % 2).toFloat()
            texture[planeIndex][squareIndex][i][1] = (i / 2).toFloat()
        }
    }

    // 获取顶点坐标
    fun getVertex(): FloatArray {
        val length = PLANE_NUM * SQUARE_NUM_PER_PLANE * VERTEXT_NUM_PER_SQUARE * DIMENSION_PER_VERTEXT
        val res = FloatArray(length)
        var index = 0
        for (i in 0 until PLANE_NUM) {
            for (j in 0 until SQUARE_NUM_PER_PLANE) {
                for (k in 0 until VERTEXT_NUM_PER_SQUARE) {
                    val ver = k * DIMENSION_PER_VERTEXT
                    for (l in 0 until DIMENSION_PER_VERTEXT) {
                        res[index++] = vertex[i][j][k][l]
                    }
                }
            }
        }
        return res
    }

    // 获取纹理坐标
    fun getTexture(): FloatArray {
        val length = PLANE_NUM * SQUARE_NUM_PER_PLANE * VERTEXT_NUM_PER_SQUARE * DIMENSION_PER_TEXTURE
        val res = FloatArray(length)
        var index = 0
        for (i in 0 until PLANE_NUM) {
            for (j in 0 until SQUARE_NUM_PER_PLANE) {
                for (k in 0 until VERTEXT_NUM_PER_SQUARE) {
                    for (l in 0 until DIMENSION_PER_TEXTURE) {
                        res[index++] = texture[i][j][k][l]
                    }
                }
            }
        }
        return res
    }

    fun getMipmap(): IntArray {
        val length = PLANE_NUM * SQUARE_NUM_PER_PLANE
        val res = IntArray(length)
        var index = 0
        for (i in 0 until PLANE_NUM) {
            for (j in 0 until SQUARE_NUM_PER_PLANE) {
                res[index++] = mipmap[i][j]
            }
        }
        return res
    }
}